home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 10.4 KB | 361 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UCommandHandler.cp
- // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UCOMMANDHANDLER__
- #include "UCommandHandler.h"
- #endif
-
- // MacApp
-
- #ifndef __UCLIPBOARDMGR__
- #include "UClipboardMgr.h"
- #endif
-
- #ifndef __UCOREERRORMGR__
- #include "UCoreErrorMgr.h"
- #endif
-
- #ifndef __UCOREGLOBALS__
- #include "UCoreGlobals.h"
- #endif
-
- #ifndef __UDEBUG__
- #include "UDebug.h"
- #endif
-
- #ifndef __UDISPATCHER__
- #include "UDispatcher.h"
- #endif
-
- // #ifndef __UERRORMGR__
- // #include "UErrorMgr.h"
- // #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- // #ifndef __UMACAPPUTILITIES__
- // #include "UMacAppUtilities.h"
- // #endif
-
- #ifndef __UMEMORY__
- #include "UMemory.h"
- #endif
-
- #ifndef __UMENUMGR__
- #include "UMenuMgr.h"
- #endif
-
- #ifndef __USCRIPTING__
- #include "UScripting.h"
- #endif
-
- #ifndef __USEGMENTS__
- #include "USegments.h"
- #endif
-
- #ifndef __UUNDO__
- #include "UUndo.h"
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- unsigned long TCommandHandler::fgTransactionIDCount;
-
- //========================================================================================
- // CLASS TCommandHandler
- //========================================================================================
- #undef Inherited
- #define Inherited TEventHandler
-
- #pragma segment MAEvtHandlerNonRes
- MA_DEFINE_CLASS_M1(TCommandHandler, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler constructor
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- TCommandHandler::TCommandHandler() :
- fPendingActionID(0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::ICommandHandler:
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- void TCommandHandler::ICommandHandler(TEventHandler* itsNextHandler)
- {
- IEventHandler(itsNextHandler);
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::Clone:
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- TCommandHandler::~TCommandHandler()
- {
- // fLastCommand = CommitACommand(fLastCommand); // commit fLastCommand
- // fLastCommand = (TCommand*)FreeIfObject(fLastCommand); // make sure it gets freed
-
- // ••• Need to check if we are in the undo history •••
-
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::DoMenuCommand:
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::HandleSetupMenus: Overridden to Adjust the Undo menu. This cannot be
- // done in an override of DoSetupMenus because TWindow::DoSetupMenus does not call the
- // Inherited method if the window is in a modal state.
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::SetupUndoMenu:
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::GetContext:
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- TCommandHandler* TCommandHandler::GetContext(CommandNumber /* aCommandNumber */)
- {
- return this;
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::PerformCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- void TCommandHandler::PerformCommand(TCommand* command)
- {
- // MAVolatileInit(TCommand*, primaryCommand, command);
- // MAVolatileInit(TCommand*, linkedCommand, command->fLinkedCommand);
-
- // Boolean cmdFreed = FALSE; // can't be volatile because
- // Boolean linkedCmdFreed = FALSE; // they are passed by reference
-
- #if qDebug
- if (!command)
- {
- ProgramBreak("NULL passed to TCommandHandler::PerformCommand");
- return;
- }
- else if (!IsObject(command))
- {
- // since it's possible to have passed in a freed undoable
- // command allocated in a global variable (due to pilot error)
- VerboseIsObject(command);
- ProgramBreak("###bogus object passed to TCommandHandler::DoPerformCommand");
- return;
- }
- #endif
-
- #if qDebugMsg
- if (gIntenseDebugging)
- fprintf(stderr, "The Command to perform: %s\n", command->GetClassName());
- #endif
-
- //Boolean wasRecurring = command->IsRecurring();
- //MAVolatileInit(TCommand*, volatileCommand, command);
-
- if (command->fUseAppleEvent && PerformCommandAppleEvent(command))
- {
- // The command has been successfully converted to an Apple Event
- // and performed as an Apple Event. We don't need it any more.
- //CommitACommand(command);
- command->Completed();
- if (command->ShouldFreeOnCompletion())
- command = (TCommand*) FreeIfObject(command);
- //cmdFreed = TRUE;
- return;
- }
-
- MAVolatileInit(TCommand*, volatileCommand, command);
- FailInfo fi;
- Try(fi)
- {
- #if qSegments
- // Unload segs except in nested event handling
- if ((gDispatcher->fEventLevel == 1)
- && (volatileCommand->NeedsToUnloadAllSegments() || MemSpaceIsLow())
- && (TOSADispatcher::fgDispatcher == NULL
- || TOSADispatcher::fgDispatcher->GetDispatchLevel() == 0))
- UnloadAllSegments();
- #endif
-
- volatileCommand->DoIt();
- volatileCommand->fCommandDone = TRUE;
- fi.Success();
- }
- else // Recover
- {
- if (volatileCommand)
- {
- volatileCommand->SetValidationError(fi.error);
-
- // Save the ID because the command is going away.
- CommandNumber aCommandNumber = volatileCommand->fIdentifier;
-
- // Abort the current transaction in the undo handler.
- // This will free the command.
- TUndoHandler::fgUndoHandler->Abort();
-
- FailNewMessage(fi.error, fi.message, BuildMessage((short)aCommandNumber, messageCommandError));
- }
- fi.ReSignal();
- }
-
- if (command)
- {
- // This is done after DoIt, so DoIt can change the fCausesChange flag.
- command->DoNotification();
-
- // Try to remove the command in case it is no longer recurring.
- gDispatcher->RemoveEvent(command);
-
- // Either set up for undo, or get rid of it
- if (command->CanBeUndone())
- command->SetupDependencies();
- else
- {
- command->Completed();
- if (command->ShouldFreeOnCompletion())
- command = (TCommand*) FreeIfObject(command);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::DoPerformCommand:
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::PerformCommandAppleEvent:
- //----------------------------------------------------------------------------------------
- #pragma segment MAApplicationRes
-
- Boolean TCommandHandler::PerformCommandAppleEvent(TCommand* command)
- {
- MAVolatileInit(TAppleEvent*, sendEvent, NULL);
- MAVolatileInit(OSErr, dispatchError, noErr);
- MAVolatileInit(long, processError, 0L);
-
- TAppleEvent *resultEvent = NULL;
-
- FailInfo fi;
- Try(fi)
- {
- sendEvent = command->MakeAppleEvent();
- if (sendEvent)
- {
- #if qDebug
- Assertion(sendEvent->GetSendingMode() != kAEQueueReply,
- "Command-based apple events must be sent synchronously");
- #endif
- if (!fgTransactionIDCount)
- fgTransactionIDCount = 1;
-
- long transactionID = fgTransactionIDCount++;
-
- sendEvent->SetTransactionID(transactionID);
- fPendingActionID = transactionID;
- dispatchError = sendEvent->SendEvent(resultEvent);
- }
- fi.Success();
- }
- else // Recover
- {
- dispatchError = fi.error;
- }
-
- if ((dispatchError == noErr) && (resultEvent != NULL))
- {
- fi.Reset();
- Try(fi)
- {
- if (resultEvent->HasParameter(keyErrorNumber))
- processError = resultEvent->ReadLong(keyErrorNumber);
- fi.Success();
- }
- else // Recover
- {
- // ignore the error
- }
- }
-
- FreeIfObject(sendEvent);
- FreeIfObject(resultEvent);
- return (dispatchError == noErr && processError == 0L);
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::GetLastCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment MAEvtHandlerRes
-
- TCommand* TCommandHandler::GetLastCommand()
- {
- // ••• We could look for commands relating to us in the undo history •••
- // ••• Maybe we don't have to •••
-
- return NULL; // fLastCommand;
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::CommitLastCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment MAApplicationRes
-
- void TCommandHandler::CommitLastCommand()
- {
- // Clear the entire action history.
- // It would be nice if we could clear only the actions that
- // affect this command handler. Unfortunately, we don't know
- // which actions depend on us, so we have to play safe.
- TUndoHandler::fgUndoHandler->ClearActionHistory(kDontRespectMarks);
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::PrepareForUndoRedo:
- //----------------------------------------------------------------------------------------
- #pragma segment MAApplicationRes
-
- void TCommandHandler::PrepareForUndoRedo(TCommand* /*command*/)
- {
- if (WantsToBeTarget())
- BecomeTarget();
- }
-
- //----------------------------------------------------------------------------------------
- // TCommandHandler::RevealUndoRedo:
- //----------------------------------------------------------------------------------------
- #pragma segment MAApplicationRes
-
- void TCommandHandler::RevealUndoRedo(TCommand* /*command*/)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // End of UCommandHandler.cp
-
- #pragma segment Inline
-